package up.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.stream.Stream;

@Service
public class SaveService {

    /**
     * 定义上传路径
     */
    public static final String SAVE_PATH = "./51-spring-boot-upload/src/main/resources/upload";

    private final Path rootLocation;

    @Autowired
    public SaveService() {
        this.rootLocation = Paths.get(SAVE_PATH);
    }


    /****************************************************************************************************************/



    /**
     * 初始化保存路径
     */
    public void init() {
        try {
            Files.createDirectories(rootLocation);
        } catch (IOException e) {
            System.out.println("初始化存储目录失败！");
            e.printStackTrace();
        }
    }

    /**
     * 递归删除目录下的文件（包括目录）
     */
    public void deleteAll() {
        FileSystemUtils.deleteRecursively(rootLocation.toFile());
    }



    /****************************************************************************************************************/


    /**
     * 上传文件并保存
     */
    public void save(MultipartFile file) {
        //规范原始路径
        String filename = StringUtils.cleanPath(file.getOriginalFilename());
        try {
            //判断文件是否为空
            if (file.isEmpty()) {
                System.out.println("文件为空，保存失败！");
            }
            //安全检查，判断是否包含双点
            if (filename.contains("..")) {
                // This is a security check
                System.out.println("文件路径中包含相对路径，不合法！");
            }
            // 将文件保存
            try (InputStream inputStream = file.getInputStream()) {
                Files.copy(inputStream, this.rootLocation.resolve(filename), StandardCopyOption.REPLACE_EXISTING);
            }
        } catch (IOException e) {
            System.out.println("保存文件失败！");
            e.printStackTrace();
        }
    }



    /**
     * 获取指定文件资源
     * @param filename
     * @return
     */
    public Resource loadAsResource(String filename) {
        try {
            Path file = load(filename);
            Resource resource = new UrlResource(file.toUri());
            if (resource.exists() || resource.isReadable()) {
                return resource;
            } else {
                System.out.println("读取文件失败，文件无法找到！");
            }
        } catch (MalformedURLException e) {
            System.out.println("读取文件失败，文件无法找到！");
            e.printStackTrace();
        }
        return null;
    }


    /****************************************************************************************************************/




    /**
     * 获取所有已上传的文件
     * @return
     */
    public Stream<Path> loadAll() {
        try {
            return Files.walk(this.rootLocation, 1).filter(path -> !path.equals(this.rootLocation)).map(this.rootLocation::relativize);
        } catch (IOException e) {
            System.out.println("获取所有文件失败！");
            e.printStackTrace();
        }
        return null;
    }





    /****************************************************************************************************************/










    /**
     * 将字符串String解析为路径path
     *
     * @param filename
     * @return
     */
    private Path load(String filename) {
        return rootLocation.resolve(filename);
    }
}
